"""
角色代码生成工具
根据角色名称自动生成符合命名规范的代码
"""
import re
from typing import Optional


# 常见角色名称映射表（中文 -> 英文代码）
ROLE_NAME_MAPPING = {
    "管理员": "admin",
    "项目经理": "project_manager",
    "项目管理员": "project_manager",
    "开发人员": "developer",
    "开发者": "developer",
    "程序员": "developer",
    "测试人员": "tester",
    "测试员": "tester",
    "QA": "tester",
    "查看者": "viewer",
    "访客": "viewer",
    "观察者": "viewer",
    "产品经理": "product_manager",
    "产品": "product_manager",
    "设计师": "designer",
    "UI设计师": "ui_designer",
    "UX设计师": "ux_designer",
    "运营": "operator",
    "运营人员": "operator",
    "运维": "devops",
    "运维人员": "devops",
    "安全": "security",
    "安全员": "security",
}


def generate_role_code(role_name: str, existing_codes: Optional[list] = None) -> str:
    """
    根据角色名称生成符合命名规范的代码
    
    规则：
    1. 如果名称在映射表中，直接使用映射值
    2. 如果名称是英文，转换为小写，空格和下划线替换为下划线
    3. 如果名称是中文，尝试使用拼音首字母或常见词汇映射
    4. 移除所有特殊字符，只保留字母、数字和下划线
    5. 如果代码已存在，添加数字后缀
    
    Args:
        role_name: 角色名称（可以是中文或英文）
        existing_codes: 已存在的角色代码列表（可选，用于避免重复）
        
    Returns:
        str: 生成的角色代码
    """
    if not role_name:
        return ""
    
    # 检查映射表
    role_name_trimmed = role_name.strip()
    if role_name_trimmed in ROLE_NAME_MAPPING:
        base_code = ROLE_NAME_MAPPING[role_name_trimmed]
    else:
        # 处理英文名称
        if re.match(r'^[a-zA-Z\s_-]+$', role_name_trimmed):
            # 英文名称：转换为小写，替换空格和连字符为下划线
            base_code = re.sub(r'[\s\-_]+', '_', role_name_trimmed.lower())
        else:
            # 中文名称：尝试提取拼音首字母或使用简化映射
            base_code = _generate_code_from_chinese(role_name_trimmed)
    
    # 清理代码：只保留字母、数字和下划线
    base_code = re.sub(r'[^a-z0-9_]', '', base_code.lower())
    
    # 确保代码不以数字开头，如果以数字开头，添加前缀
    if base_code and base_code[0].isdigit():
        base_code = f"role_{base_code}"
    
    # 确保代码不为空
    if not base_code:
        base_code = "role"
    
    # 检查是否已存在，如果存在则添加数字后缀
    if existing_codes:
        final_code = base_code
        counter = 1
        while final_code in existing_codes:
            final_code = f"{base_code}_{counter}"
            counter += 1
        return final_code
    
    return base_code


def _generate_code_from_chinese(chinese_name: str) -> str:
    """
    从中文名称生成代码
    
    使用简化的映射规则：
    1. 提取常见词汇的英文翻译
    2. 使用拼音首字母（简化版）
    """
    # 常见中文字词映射
    word_mapping = {
        "项目": "project",
        "管理": "manager",
        "经理": "manager",
        "开发": "developer",
        "测试": "tester",
        "查看": "viewer",
        "产品": "product",
        "设计": "design",
        "运营": "operator",
        "运维": "devops",
        "安全": "security",
        "人员": "",
        "员": "",
        "者": "",
        "师": "",
    }
    
    # 尝试提取关键词
    words = []
    for word, eng in word_mapping.items():
        if word in chinese_name:
            if eng:
                words.append(eng)
            chinese_name = chinese_name.replace(word, "")
    
    # 如果提取到了关键词，组合生成代码
    if words:
        return "_".join(words)
    
    # 如果没有匹配到，使用拼音首字母（简化版）
    # 这里使用一个简单的映射表，实际项目中可以使用 pypinyin 库
    pinyin_initials = {
        "项": "x", "目": "m", "经": "j", "理": "l",
        "开": "k", "发": "f", "测": "c", "试": "s",
        "查": "c", "看": "k", "产": "c", "品": "p",
        "设": "s", "计": "j", "运": "y", "维": "w",
        "安": "a", "全": "q", "人": "r", "员": "y",
    }
    
    # 提取每个字的拼音首字母
    initials = []
    for char in chinese_name:
        if char in pinyin_initials:
            initials.append(pinyin_initials[char])
        elif '\u4e00' <= char <= '\u9fff':  # 中文字符范围
            # 对于不在映射表中的中文字符，使用第一个Unicode字节
            # 这里简化处理，实际应该使用拼音库
            pass
    
    if initials:
        return "".join(initials)
    
    # 如果都匹配不到，返回默认值
    return "custom_role"


def validate_role_code(code: str) -> bool:
    """
    验证角色代码是否符合命名规范
    
    规则：
    - 只能包含小写字母、数字和下划线
    - 不能以数字开头
    - 长度在 1-50 之间
    
    Args:
        code: 角色代码
        
    Returns:
        bool: 是否符合规范
    """
    if not code:
        return False
    
    if len(code) < 1 or len(code) > 50:
        return False
    
    # 检查是否只包含字母、数字和下划线
    if not re.match(r'^[a-z][a-z0-9_]*$', code):
        return False
    
    return True


def normalize_role_code(code: str) -> str:
    """
    规范化角色代码
    
    将代码转换为符合命名规范的格式：
    - 转换为小写
    - 替换空格和连字符为下划线
    - 移除特殊字符
    - 确保不以数字开头
    
    Args:
        code: 原始代码
        
    Returns:
        str: 规范化后的代码
    """
    if not code:
        return ""
    
    # 转换为小写
    normalized = code.lower()
    
    # 替换空格和连字符为下划线
    normalized = re.sub(r'[\s\-]+', '_', normalized)
    
    # 移除所有特殊字符，只保留字母、数字和下划线
    normalized = re.sub(r'[^a-z0-9_]', '', normalized)
    
    # 确保不以数字开头
    if normalized and normalized[0].isdigit():
        normalized = f"role_{normalized}"
    
    # 确保代码不为空
    if not normalized:
        normalized = "role"
    
    return normalized

